package org.cupk2.tools.files;

import org.mozilla.universalchardet.UniversalDetector;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Cupk2FileUtils {

    /**
     * @param path 递归删除指定目录及其所有子目录和文件
     * @throws IOException
     */
    public static void deleteFolderRecursively(Path path) throws IOException {
        if (Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) {
            try (DirectoryStream<Path> entries = Files.newDirectoryStream(path)) {
                for (Path entry : entries) {
                    deleteFolderRecursively(entry);
                }
            }
        }
        Files.delete(path);
    }

    /**
     * 拷贝文件
     *
     * @param file              原文件
     * @param toFile            目标文件
     * @param cupk2ProcessState 拷贝进度 Cupk2ProcessState.setPercent(int percent)
     */
    public static void copyTo(File file, File toFile, Cupk2ProcessState cupk2ProcessState) {

        File parentDir = toFile.getParentFile();
        if (!parentDir.exists() && !parentDir.mkdirs()) {
            throw new RuntimeException("无法创建目标文件的父目录: " + parentDir.getAbsolutePath());
        }
        try (InputStream is = new FileInputStream(file); OutputStream os = new FileOutputStream(toFile)) {
            long fileSize = file.length();
            byte[] buffer = new byte[1024];
            int length;
            long totalRead = 0;

            while ((length = is.read(buffer)) > 0) {
                os.write(buffer, 0, length);
                totalRead += length;

                int percent = (int) ((totalRead * 100) / fileSize);
                cupk2ProcessState.setPercent(percent);
            }
        } catch (IOException e) {

            throw new RuntimeException("文件拷贝失败: " + e.getMessage(), e);
        }
    }

    /**
     * 读取文本文件内容，支持指定编码方式。
     *
     * @param textFile    文本文件对象
     * @param charsetName 编码方式名称，默认为 "UTF-8"
     * @return 文件内容字符串
     * @throws IOException 如果发生 I/O 错误
     */
    public static String readText(File textFile, String charsetName) throws IOException {

        if (charsetName == null || charsetName.isEmpty()) {
            charsetName = "UTF-8";
        }

        try {
            return new String(Files.readAllBytes(textFile.toPath()), Charset.forName(charsetName));
        } catch (IOException e) {
            throw new IOException("无法读取文件: " + textFile.getAbsolutePath(), e);
        }
    }

    public static String readText(File textFile) throws IOException {
        return readText(textFile, "UTF-8");
    }

    public static String readFile(String filePath) {
        try {
            File file = new File(filePath);

            byte[] fileContentBytes;
            try (FileInputStream fis = new FileInputStream(file)) {
                fileContentBytes = fis.readAllBytes();
            }

            UniversalDetector detector = new UniversalDetector(null);
            detector.handleData(fileContentBytes, 0, fileContentBytes.length);
            detector.dataEnd();
            String detectedEncoding = detector.getDetectedCharset();
            detector.reset();

            if (detectedEncoding == null || "windows-1252".equals(detectedEncoding)) {

                Charset gbk = Charset.forName("GBK");
                try {
                    String content = new String(fileContentBytes, gbk);

                    if (content.getBytes(gbk).length == fileContentBytes.length) {
                        return content;
                    }
                } catch (Exception e) {

                }

                detectedEncoding = Charset.defaultCharset().name();
            }

            return new String(fileContentBytes, detectedEncoding);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void writeToFile(String text, File textFile) {

        if (!textFile.getParentFile().exists() && !textFile.getParentFile().mkdirs()) {
            System.out.println("Failed to create directory for file." + textFile.getPath());
            return;
        }
        BufferedWriter writer = null;
        try {

            writer = new BufferedWriter(new FileWriter(textFile, false)); // 'true'参数表示以追加模式打开文件

            writer.write(text);

            writer.newLine();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 按文件名排序
     *
     * @param path
     * @return
     */
    public static List<File> getSortedFiles(Path path) {

        if (path == null || !path.toFile().isDirectory()) {
            throw new IllegalArgumentException("Path must be a valid directory.");
        }

        return Arrays.stream(path.toFile().listFiles())
                .sorted((f1, f2) -> f1.getName().compareTo(f2.getName())) // 按文件名排序
                .collect(Collectors.toList());
    }

    public static String getExName(File targetFile) {
        String fileName = targetFile.getName();
        if (fileName == null || fileName.isEmpty()) {
            return "";
        }
        int lastIndexOfDot = fileName.lastIndexOf('.');

        if (lastIndexOfDot == -1 || lastIndexOfDot == fileName.length() - 1) {
            return "";
        }
        return fileName.substring(lastIndexOfDot + 1);
    }

    /**
     * 是否为图片
     *
     * @param exname
     * @return
     */
    public static boolean isImg(String exname) {


        if (exname == null || exname.isEmpty()) {
            return false;
        }

        String[] imgExts = {"jpg", "jpeg", "png", "gif", "webp",

        };

        exname = exname.toLowerCase();

        for (String ext : imgExts) {
            if (exname.equals(ext)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 判断一个图片的长宽比是否满足1:1.6到1:1.2之间
     *
     * @param file   文件
     * @param exname 扩展名（用于简单校验）
     * @return 如果长宽比在范围内返回true，否则返回false
     */
    public static boolean viewImg(File file, String exname) {

        if (file == null || !file.exists() || exname == null || exname.isEmpty()) {
            return false;
        }

        long maxSize = 1024 * 1024; // 1MB
        if (file.length() > maxSize) {
            return false; // 文件过大，不处理
        }

        try {

            String lowerExname = exname.toLowerCase();
            if (!lowerExname.equals("jpg") && !lowerExname.equals("jpeg") && !lowerExname.equals("png") && !lowerExname.equals("gif")) {
                return false; // 不支持的图片格式
            }

            BufferedImage image = ImageIO.read(file);

            if (image == null) {
                return false; // 无法读取图片
            }

            int width = image.getWidth();
            int height = image.getHeight();

            if (width <= 0 || height <= 0) {
                return false; // 图片尺寸无效
            }

            double ratio = (double) width / height;
            double ratioB = (double) height / width;

            return (ratio >= 1 && ratio <= 2) || (ratioB >= 1 && ratioB <= 2);
        } catch (Exception e) {

            return false;
        }
    }

    /**
     * 获取当前项目所在文件目录地址
     *
     * @return 当前classpath对应的文件目录路径
     */
    public static File getDefaultFileBasePath(String path) {
        try {
            File basePath = new File(System.getProperty("user.dir")).getAbsoluteFile();
            if (basePath != null) {
                return basePath.toPath().getRoot().toFile().toPath().resolve(Path.of("zhzmFiles").resolve(path)).toFile(); // 获取磁盘根目录
            }
            throw new FileNotFoundException("无法获得默认目录");
        } catch (Exception e) {
            e.printStackTrace();
            return new File(System.getProperty("user.home")); // 默认返回用户主目录
        }
    }

}
